<!-- Copyright (C) 2012-2025 Zammad Foundation, https://zammad-foundation.org/ -->

<script setup lang="ts">
import { useEventListener } from '@vueuse/core'
import { markRaw, shallowRef } from 'vue'

import { Events } from './manage.ts'

import type { DestroyComponentData, PushComponentData } from './types.ts'
import type { TransitionProps } from 'vue'

const props = defineProps<{
  /**
   * Name of a group of components that will be pushed to with unique ID.
   */
  name: string
  /**
   * Transition, if any.
   */
  transition?: TransitionProps
}>()

const components = shallowRef<PushComponentData[]>([])

useEventListener(window, Events.Push, ({ detail }: CustomEvent<PushComponentData>) => {
  if (detail.name !== props.name) return

  components.value = [
    ...components.value,
    {
      ...detail,
      cmp: markRaw(detail.cmp),
    },
  ]
})

useEventListener(window, Events.Destroy, ({ detail }: CustomEvent<DestroyComponentData>) => {
  if (detail.name !== props.name) return

  if (!detail.id) {
    components.value = []

    return
  }

  components.value = components.value.filter(
    (item) => !(item.name === detail.name && item.id === detail.id),
  )
})
</script>

<template>
  <TransitionGroup v-if="transition" v-bind="transition">
    <Component
      :is="cmp"
      v-for="{ cmp, name: cmpName, id, props: cmpProps } in components"
      :key="`${cmpName}-${id}`"
      v-bind="cmpProps"
    />
  </TransitionGroup>

  <template v-else-if="!$slots.default">
    <Component
      :is="cmp"
      v-for="{ cmp, name: cmpName, id, props: cmpProps } in components"
      :key="`${cmpName}-${id}`"
      v-bind="cmpProps"
    />
  </template>

  <slot v-else :components="components" />
</template>
